﻿using System.Collections.ObjectModel;

using Game.Common;
using Game.Level;
using Game.Map;

namespace Game.StateMachine
{
    public class Machine : State
    {
        class StateIdMachine : StateId
        {
            public StateIdMachine() : base("Machine") {}
        }
        
        readonly Collection<State> _States = new Collection<State>();
        
        State _DefaultState;
        State _CurrentState;
        State _GoalState;
        StateId _GoalId;
        
        public Machine()
            : base(new StateIdMachine())
        {}

        public override void DoTurn(
            IGameMapView view, 
            GameLevels levels,
            object controller, 
            GameTurn turn)
        {
            if (_States.Count == 0)
            {
                return;
            }
            
            if (_CurrentState == null)
            {
                _CurrentState = _DefaultState;
            }
            if (_CurrentState == null)
            {
                return;
            }
            
            StateId oldStateId = _CurrentState.Id;
            _GoalId = _CurrentState.CheckTransitions(controller);
            
            if (_GoalId != oldStateId)
            {
                if (TransitionState(_GoalId))
                {
                    _CurrentState.Exit();
                    _CurrentState = _GoalState;
                    _CurrentState.Enter();
                }
            }
            
            _CurrentState.DoTurn(view, levels, controller, turn);
        }
        
        public bool TransitionState(StateId goal)
        {
            //don't do anything if you have no states   
            if(_States.Count == 0 )
            {
                return false;   
            }
            
            //determine if we have state of type 'goal'   
            //in the list, and switch to it, otherwise, quit out   
            for(int i = 0; i < _States.Count; i++)   
            {   
                if(_States[i].Id == goal)   
                {   
                    _GoalState = _States[i];   
                    return true;   
                }   
            }   
            return false;   
        }
        
        public void AddState(State state)
        {
            _States.Add(state);
        }
        
        public void Reset()
        {
            Exit();
            if(_CurrentState != null)
            {
                _CurrentState.Exit();   
            }
            _CurrentState = _DefaultState;   
            
            //init all the states   
            for(int i =0; i < _States.Count; i++)
            {
                _States[i].Init();   
            }
            
            //and now enter the m_defaultState, if any   
            if(_CurrentState != null)
            {
                _CurrentState.Enter();   
            }
        }
        
        public State DefaultState
        {
            get { return _DefaultState; }
            set { _DefaultState = value; }
        }
        
        public StateId GoalId
        {
            get { return _GoalId; }
            set { _GoalId = value; }
        }
        
    }
}
